﻿using System;
using System.ComponentModel;
using System.Text;
using estoque.Model;

namespace estoque.ViewModel
{
    public class WorkItemVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        internal WorkItem WorkItem { get; set; }

        private string shortInfo;

        public string Title
        {
            get { return this.WorkItem.Title; }
            set { this.WorkItem.Title = value; InvokePropertyChanged("Title"); }
        }

        public Nullable<DateTime> DueDate
        {
            get { return this.WorkItem.DueDate; }
            set { this.WorkItem.DueDate = value; InvokePropertyChanged("DueDate"); InvokePropertyChanged("IsExpired"); }
        }

        public bool IsFinished
        {
            get { return this.WorkItem.IsFinished; }
            set { this.WorkItem.IsFinished = value; InvokePropertyChanged("IsFinished"); }
        }

        public Nullable<int> TfsScenarioId
        {
            get { return this.WorkItem.TfsScenarioId; }
            set { this.WorkItem.TfsScenarioId = value; InvokePropertyChanged("TfsScenarioId"); InvokePropertyChanged("IsTfsSynced"); }
        }

        public bool IsTfsSynced
        {
            get { return this.WorkItem.TfsScenarioId.HasValue; }
        }

        public bool IsExpired
        {
            get
            {
                if (!this.DueDate.HasValue) return false;
                return DateTime.Now.Subtract(this.DueDate.Value).TotalDays > 0;
            }
        }

        public bool WillExpired
        {
            get
            {
                if (!this.DueDate.HasValue) return false;
                if (this.IsExpired) return false;
                return this.DueDate.Value.Subtract(DateTime.Now).TotalDays < 7;
            }
        }

        public string DueDateString
        {
            get
            {
                if (!this.DueDate.HasValue)
                {
                    return string.Empty;
                }
                if (this.IsExpired)
                {
                    double delta = DateTime.Now.Subtract(this.DueDate.Value).TotalDays;

                    if (delta > 0 && delta < 1)
                    {
                        return "heute";
                    }
                    else if (delta > 1 && delta < 2)
                    {
                        return "gestern";
                    }
                    return "vor " + delta.ToString("N0") + " Tagen";
                }
                else if (this.WillExpired)
                {
                    double delta = this.DueDate.Value.Subtract(DateTime.Now).TotalDays;

                    if (delta > 0 && delta < 1)
                    {
                        return "heute";
                    }
                    else if (delta > 1 && delta < 2)
                    {
                        return "morgen";
                    }

                    return "in " + delta.ToString("N0") + " Tagen";
                }

                return "am " + this.DueDate.Value.ToString("dd.MM.yyyy");
            }
        }

        protected bool IsDirty { get; set; }

        public string ShortInfo
        {
            get
            {
                if (this.IsDirty || string.IsNullOrWhiteSpace(this.shortInfo))
                {
                    StringBuilder sb = new StringBuilder();
                    if (this.DueDate.HasValue)
                        sb.AppendLine((this.IsExpired ? "lief " : "läuft ") + "ab: " + this.DueDateString);
                    if (this.IsTfsSynced)
                        sb.AppendLine("im TFS hinterlegt als #" + this.TfsScenarioId);
                    if (this.IsFinished)
                        sb.AppendLine("Status: erledigt");
                    else if (this.IsExpired)
                        sb.AppendLine("Status: abgelaufen");
                    else if (this.WillExpired)
                        sb.AppendLine("Status: zu erledigen");
                    else
                        sb.AppendLine("Status: offen");
                    this.shortInfo = sb.ToString();
                    this.IsDirty = false;
                }

                return this.shortInfo;
            }
        }

        public WorkItemVM(WorkItem workItem)
        {
            this.WorkItem = workItem;
        }

        public WorkItemVM()
        {
            this.IsDirty = true;
        }

        internal void InvokePropertyChanged(string propertyName)
        {
            this.IsDirty = true;
            PropertyChangedEventHandler temp = this.PropertyChanged;
            if (temp != null)
            {
                temp(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}